[XEN] Implement rate-limited logging.
authorkaf24@localhost.localdomain <kaf24@localhost.localdomain>
Fri, 27 Oct 2006 17:46:20 +0000 (18:46 +0100)
committerkaf24@localhost.localdomain <kaf24@localhost.localdomain>
Fri, 27 Oct 2006 17:46:20 +0000 (18:46 +0100)
Taken from Andi Kleen's rate limit in the Linux kernel.

This keeps large amounts of prints in the HV down.

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
xen/arch/x86/mm.c
xen/drivers/char/console.c
xen/include/xen/lib.h

index f5098d9038861473890c82ebb46c838643a6699e..5f3292ac382aee345dffdb9a83a5a3dbef9b9bb2 100644 (file)
 #include <public/memory.h>
 
 #ifdef VERBOSE
-#define MEM_LOG(_f, _a...)                                  \
-  printk("DOM%u: (file=mm.c, line=%d) " _f "\n",            \
-         current->domain->domain_id , __LINE__ , ## _a )
+#define MEM_LOG(_f, _a...)                                          \
+    do {                                                            \
+        if ( printk_ratelimit() )                                   \
+            printk("DOM%u: (file=mm.c, line=%d) " _f "\n",          \
+                   current->domain->domain_id , __LINE__ , ## _a ); \
+    } while (0)
 #else
 #define MEM_LOG(_f, _a...) ((void)0)
 #endif
index 235d6fefd882bd4eede3e48dc110589e73c816ce..e6a89016b0f40703d93a3a03f66ff0e092b26aef 100644 (file)
@@ -4,6 +4,10 @@
  * Emergency console I/O for Xen and the domain-0 guest OS.
  * 
  * Copyright (c) 2002-2004, K A Fraser.
+ *
+ * Added printf_ratelimit
+ *     Taken from Linux - Author: Andi Kleen (net_ratelimit)
+ *     Ported to Xen - Steven Rostedt - Red Hat
  */
 
 #include <xen/stdarg.h>
@@ -26,6 +30,7 @@
 #include <asm/current.h>
 #include <asm/debugger.h>
 #include <asm/io.h>
+#include <asm/div64.h>
 
 /* console: comma-separated list of console outputs. */
 static char opt_console[30] = OPT_CONSOLE_STR;
@@ -448,6 +453,56 @@ int console_getc(void)
     return serial_getc(sercon_handle);
 }
 
+/*
+ * printk rate limiting, lifted from Linux.
+ *
+ * This enforces a rate limit: not more than one kernel message
+ * every printk_ratelimit_ms (millisecs).
+ */
+int __printk_ratelimit(int ratelimit_ms, int ratelimit_burst)
+{
+    static DEFINE_SPINLOCK(ratelimit_lock);
+    static unsigned long toks = 10 * 5 * 1000;
+    static unsigned long last_msg;
+    static int missed;
+    unsigned long flags;
+    unsigned long long now = NOW(); /* ns */
+    unsigned long ms;
+
+    do_div(now, 1000000);
+    ms = (unsigned long)now;
+
+    spin_lock_irqsave(&ratelimit_lock, flags);
+    toks += ms - last_msg;
+    last_msg = ms;
+    if ( toks > (ratelimit_burst * ratelimit_ms))
+        toks = ratelimit_burst * ratelimit_ms;
+    if ( toks >= ratelimit_ms )
+    {
+        int lost = missed;
+        missed = 0;
+        toks -= ratelimit_ms;
+        spin_unlock_irqrestore(&ratelimit_lock, flags);
+        if ( lost )
+            printk("printk: %d messages suppressed.\n", lost);
+        return 1;
+    }
+    missed++;
+    spin_unlock_irqrestore(&ratelimit_lock, flags);
+    return 0;
+}
+
+/* minimum time in ms between messages */
+int printk_ratelimit_ms = 5 * 1000;
+
+/* number of messages we send before ratelimiting */
+int printk_ratelimit_burst = 10;
+
+int printk_ratelimit(void)
+{
+    return __printk_ratelimit(printk_ratelimit_ms,
+                              printk_ratelimit_burst);
+}
 
 /*
  * **************************************************************
index f333c3f14b2aceb0505ad66cbab749c835a77449..8af65e1ed8fb16b916d2a7e3bae7fc8cee5e7dc5 100644 (file)
@@ -56,6 +56,8 @@ extern void printk(const char *format, ...)
 extern void panic(const char *format, ...)
     __attribute__ ((format (printf, 1, 2)));
 extern long vm_assist(struct domain *, unsigned int, unsigned int);
+extern int __printk_ratelimit(int ratelimit_ms, int ratelimit_burst);
+extern int printk_ratelimit(void);
 
 /* vsprintf.c */
 extern int sprintf(char * buf, const char * fmt, ...)